package com.platform.common.redis;

import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.Tuple;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 实现jedis连接的获取和释放，具体的redis业务逻辑由executor实现
 * 
 * @author LiangMingHui
 *
 */
public interface RedisService {

	public String set(final String key, final String value);

	public String set(final String key, final String value, final String nxxx, final String expx, final long time);

	public String get(final String key);

	public Boolean exists(final String key);

	public Long setnx(final String key, final String value);

	public String setex(final String key, final int seconds, final String value);

	public Long expire(final String key, final int seconds);

	public Long incr(final String key);

	public Long decr(final String key);

	public Long hset(final String key, final String field, final String value);

	public String hget(final String key, final String field);

	public String hmset(final String key, final Map<String, String> hash);

	public List<String> hmget(final String key, final String... fields);

	public Long del(final String key);

	public Map<String, String> hgetAll(final String key);

	public void destroy();

	public Object getObject(String key);

	public Object setObject(String cacheKey, Object value, int expireTime);

	public List<Object> keysObject(String string);

	public ScanResult<String> scan(final String cursor);

	public ScanResult<String> scan(final String cursor, final ScanParams params);

	/**
	 * Add the specified member having the specifeid score to the sorted set
	 * stored at key. If member is already a member of the sorted set the score
	 * is updated, and the element reinserted in the right position to ensure
	 * sorting. If key does not exist a new sorted set with the specified member
	 * as sole member is crated. If the key exists but does not hold a sorted
	 * set value an error is returned.
	 * <p>
	 * The score value can be the string representation of a double precision
	 * floating point number.
	 * <p>
	 * Time complexity O(log(N)) with N being the number of elements in the
	 * sorted set
	 * 
	 * @param key
	 * @param score
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the sorted set and the score
	 *         was updated
	 */
	public Long zadd(final String key, final double score, final String member);

	public Long zadd(final String key, final Map<String, Double> scoreMembers);

	/**
	 * If member already exists in the sorted set adds the increment to its
	 * score and updates the position of the element in the sorted set
	 * accordingly. If member does not already exist in the sorted set it is
	 * added with increment as score (that is, like if the previous score was
	 * virtually zero). If key does not exist a new sorted set with the
	 * specified member as sole member is crated. If the key exists but does not
	 * hold a sorted set value an error is returned.
	 * <p>
	 * The score value can be the string representation of a double precision
	 * floating point number. It's possible to provide a negative value to
	 * perform a decrement.
	 * <p>
	 * For an introduction to sorted sets check the Introduction to Redis data
	 * types page.
	 * <p>
	 * Time complexity O(log(N)) with N being the number of elements in the
	 * sorted set
	 * 
	 * @param key
	 * @param score
	 * @param member
	 * @return The new score
	 */
	public Double zincrby(final String key, final double score, final String member);

	/**
	 * Return the sorted set cardinality (number of elements). If the key does
	 * not exist 0 is returned, like for empty sorted sets.
	 * <p>
	 * Time complexity O(1)
	 * 
	 * @param key
	 * @return the cardinality (number of elements) of the set as an integer.
	 */
	public Long zcard(final String key);

	/**
	 * Creates a union or intersection of N sorted sets given by keys k1 through
	 * kN, and stores it at dstkey. It is mandatory to provide the number of
	 * input keys N, before passing the input keys and the other (optional)
	 * arguments.
	 * <p>
	 * As the terms imply, the {@link #zinterstore(String, String...)
	 * ZINTERSTORE} command requires an element to be present in each of the
	 * given inputs to be inserted in the result. The
	 * {@link #zunionstore(String, String...) ZUNIONSTORE} command inserts all
	 * elements across all inputs.
	 * <p>
	 * Using the WEIGHTS option, it is possible to add weight to each input
	 * sorted set. This means that the score of each element in the sorted set
	 * is first multiplied by this weight before being passed to the
	 * aggregation. When this option is not given, all weights default to 1.
	 * <p>
	 * With the AGGREGATE option, it's possible to specify how the results of
	 * the union or intersection are aggregated. This option defaults to SUM,
	 * where the score of an element is summed across the inputs where it
	 * exists. When this option is set to be either MIN or MAX, the resulting
	 * set will contain the minimum or maximum score of an element across the
	 * inputs where it exists.
	 * <p>
	 * <b>Time complexity:</b> O(N) + O(M log(M)) with N being the sum of the
	 * sizes of the input sorted sets, and M being the number of elements in the
	 * resulting sorted set
	 * 
	 * @param dstkey
	 * @param sets
	 * @return Integer reply, specifically the number of elements in the sorted
	 *         set at dstkey
	 */
	public Long zinterstore(final String dstkey, final String... sets);

	/**
	 * <p>
	 * <strong>起始版本：1.2.0</strong>
	 * </p>
	 * <p>
	 * <strong>时间复杂度：</strong>O(log(N)+M) with N being the number of elements in
	 * the sorted set and M the number of elements returned.
	 * </p>
	 * <p>
	 * Returns the specified range of elements in the sorted set stored at
	 * <code class="highlighter-rouge">key</code>. The elements are considered
	 * to be ordered from the lowest to the highest score. Lexicographical order
	 * is used for elements with equal score.
	 * </p>
	 * 
	 * <p>
	 * See <code class="highlighter-rouge">ZREVRANGE</code> when you need the
	 * elements ordered from highest to lowest score (and descending
	 * lexicographical order for elements with equal score).
	 * </p>
	 * 
	 * <p>
	 * Both <code class="highlighter-rouge">start</code> and
	 * <code class="highlighter-rouge">stop</code> are zero-based indexes, where
	 * <code class="highlighter-rouge">0</code> is the first element,
	 * <code class="highlighter-rouge">1</code> is the next element and so on.
	 * They can also be negative numbers indicating offsets from the end of the
	 * sorted set, with <code class="highlighter-rouge">-1</code> being the last
	 * element of the sorted set, <code class="highlighter-rouge">-2</code> the
	 * penultimate element and so on.
	 * </p>
	 * 
	 * <p>
	 * <code class="highlighter-rouge">start</code> and
	 * <code class="highlighter-rouge">stop</code> are <strong>inclusive
	 * ranges</strong>, so for example
	 * <code class="highlighter-rouge">ZRANGE myzset 0 1</code>` will return
	 * both the first and the second element of the sorted set.
	 * </p>
	 * 
	 * <p>
	 * Out of range indexes will not produce an error. If
	 * <code class="highlighter-rouge">start</code> is larger than the largest
	 * index in the sorted set, or
	 * <code class="highlighter-rouge">start &gt;	stop</code>, an empty list
	 * is returned. If <code class="highlighter-rouge">stop</code> is larger
	 * than the end of the sorted set Redis will treat it like it is the last
	 * element of the sorted set.
	 * </p>
	 * 
	 * <p>
	 * It is possible to pass the
	 * <code class="highlighter-rouge">WITHSCORES</code> option in order to
	 * return the scores of the elements together with the elements. The
	 * returned list will contain
	 * <code class="highlighter-rouge">value1,score1,...,valueN,scoreN</code>
	 * instead of <code class="highlighter-rouge">value1,...,valueN</code>.
	 * Client libraries are free to return a more appropriate data type
	 * (suggestion: an array with (value, score) arrays/tuples).
	 * </p>
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */
	public Set<String> zrange(final String key, final long start, final long end);

	public Set<Tuple> zrangeWithScores(final String key, final long start, final long end);

	/**
	 * Return the all the elements in the sorted set at key with a score between
	 * min and max (including elements with score equal to min or max).
	 * <p>
	 * The elements having the same score are returned sorted lexicographically
	 * as ASCII strings (this follows from a property of Redis sorted sets and
	 * does not involve further computation).
	 * <p>
	 * Using the optional
	 * {@link #zrangeByScore(String, double, double, int, int) LIMIT} it's
	 * possible to get only a range of the matching elements in an SQL-alike
	 * way. Note that if offset is large the commands needs to traverse the list
	 * for offset elements and this adds up to the O(M) figure.
	 * <p>
	 * The {@link #zcount(String, double, double) ZCOUNT} command is similar to
	 * {@link #zrangeByScore(String, double, double) ZRANGEBYSCORE} but instead
	 * of returning the actual elements in the specified interval, it just
	 * returns the number of matching elements.
	 * <p>
	 * <b>Exclusive intervals and infinity</b>
	 * <p>
	 * min and max can be -inf and +inf, so that you are not required to know
	 * what's the greatest or smallest element in order to take, for instance,
	 * elements "up to a given value".
	 * <p>
	 * Also while the interval is for default closed (inclusive) it's possible
	 * to specify open intervals prefixing the score with a "(" character, so
	 * for instance:
	 * <p>
	 * {@code ZRANGEBYSCORE zset (1.3 5}
	 * <p>
	 * Will return all the values with score &gt; 1.3 and &lt;= 5, while for
	 * instance:
	 * <p>
	 * {@code ZRANGEBYSCORE zset (5 (10}
	 * <p>
	 * Will return all the values with score &gt; 5 and &lt; 10 (5 and 10
	 * excluded).
	 * <p>
	 * <b>Time complexity:</b>
	 * <p>
	 * O(log(N))+O(M) with N being the number of elements in the sorted set and
	 * M the number of elements returned by the command, so if M is constant
	 * (for instance you always ask for the first ten elements with LIMIT) you
	 * can consider it O(log(N))
	 * 
	 * @see #zrangeByScore(String, double, double)
	 * @see #zrangeByScore(String, double, double, int, int)
	 * @see #zrangeByScoreWithScores(String, double, double)
	 * @see #zrangeByScoreWithScores(String, String, String)
	 * @see #zrangeByScoreWithScores(String, double, double, int, int)
	 * @see #zcount(String, double, double)
	 * @param key
	 * @param min
	 *            a double or Double.MIN_VALUE for "-inf"
	 * @param max
	 *            a double or Double.MAX_VALUE for "+inf"
	 * @return Multi bulk reply specifically a list of elements in the specified
	 *         score range.
	 */
	public Set<String> zrangeByScore(final String key, final double min, final double max);

	/**
	 * Return the all the elements in the sorted set at key with a score between
	 * min and max (including elements with score equal to min or max).
	 * <p>
	 * The elements having the same score are returned sorted lexicographically
	 * as ASCII strings (this follows from a property of Redis sorted sets and
	 * does not involve further computation).
	 * <p>
	 * Using the optional
	 * {@link #zrangeByScore(String, double, double, int, int) LIMIT} it's
	 * possible to get only a range of the matching elements in an SQL-alike
	 * way. Note that if offset is large the commands needs to traverse the list
	 * for offset elements and this adds up to the O(M) figure.
	 * <p>
	 * The {@link #zcount(String, double, double) ZCOUNT} command is similar to
	 * {@link #zrangeByScore(String, double, double) ZRANGEBYSCORE} but instead
	 * of returning the actual elements in the specified interval, it just
	 * returns the number of matching elements.
	 * <p>
	 * <b>Exclusive intervals and infinity</b>
	 * <p>
	 * min and max can be -inf and +inf, so that you are not required to know
	 * what's the greatest or smallest element in order to take, for instance,
	 * elements "up to a given value".
	 * <p>
	 * Also while the interval is for default closed (inclusive) it's possible
	 * to specify open intervals prefixing the score with a "(" character, so
	 * for instance:
	 * <p>
	 * {@code ZRANGEBYSCORE zset (1.3 5}
	 * <p>
	 * Will return all the values with score &gt; 1.3 and &lt;= 5, while for
	 * instance:
	 * <p>
	 * {@code ZRANGEBYSCORE zset (5 (10}
	 * <p>
	 * Will return all the values with score &gt; 5 and &lt; 10 (5 and 10
	 * excluded).
	 * <p>
	 * <b>Time complexity:</b>
	 * <p>
	 * O(log(N))+O(M) with N being the number of elements in the sorted set and
	 * M the number of elements returned by the command, so if M is constant
	 * (for instance you always ask for the first ten elements with LIMIT) you
	 * can consider it O(log(N))
	 * 
	 * @see #zrangeByScore(String, double, double)
	 * @see #zrangeByScore(String, double, double, int, int)
	 * @see #zrangeByScoreWithScores(String, double, double)
	 * @see #zrangeByScoreWithScores(String, double, double, int, int)
	 * @see #zcount(String, double, double)
	 * @param key
	 * @param min
	 * @param max
	 * @return Multi bulk reply specifically a list of elements in the specified
	 *         score range.
	 */
	public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max);

	/**
	 * Return the rank (or index) or member in the sorted set at key, with
	 * scores being ordered from low to high.
	 * <p>
	 * When the given member does not exist in the sorted set, the special value
	 * 'nil' is returned. The returned rank (or index) of the member is 0-based
	 * for both commands.
	 * <p>
	 * <b>Time complexity:</b>
	 * <p>
	 * O(log(N))
	 * 
	 * @see #zrevrank(String, String)
	 * @param key
	 * @param member
	 * @return Integer reply or a nil bulk reply, specifically: the rank of the
	 *         element as an integer reply if the element exists. A nil bulk
	 *         reply if there is no such element.
	 */
	public Long zrank(final String key, final String member);

	/**
	 * Remove the specified member from the sorted set value stored at key. If
	 * member was not a member of the set no operation is performed. If key does
	 * not not hold a set value an error is returned.
	 * <p>
	 * Time complexity O(log(N)) with N being the number of elements in the
	 * sorted set
	 * 
	 * @param key
	 * @param members
	 * @return Integer reply, specifically: 1 if the new element was removed 0
	 *         if the new element was not a member of the set
	 */
	public Long zrem(final String key, final String... members);

	/**
	 * Remove all elements in the sorted set at key with rank between start and
	 * end. Start and end are 0-based with rank 0 being the element with the
	 * lowest score. Both start and end can be negative numbers, where they
	 * indicate offsets starting at the element with the highest rank. For
	 * example: -1 is the element with the highest score, -2 the element with
	 * the second highest score and so forth.
	 * <p>
	 * <b>Time complexity:</b> O(log(N))+O(M) with N being the number of
	 * elements in the sorted set and M the number of elements removed by the
	 * operation
	 */
	public Long zremrangeByRank(final String key, final long start, final long end);

	/**
	 * Remove all the elements in the sorted set at key with a score between min
	 * and max (including elements with score equal to min or max).
	 * <p>
	 * <b>Time complexity:</b>
	 * <p>
	 * O(log(N))+O(M) with N being the number of elements in the sorted set and
	 * M the number of elements removed by the operation
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return Integer reply, specifically the number of elements removed.
	 */
	public Long zremrangeByScore(final String key, final double start, final double end);

	public ScanResult<Tuple> zscan(final String key, final String cursor);

	/**
	 * Return the score of the specified element of the sorted set at key. If
	 * the specified element does not exist in the sorted set, or the key does
	 * not exist at all, a special 'nil' value is returned.
	 * <p>
	 * <b>Time complexity:</b> O(1)
	 * 
	 * @param key
	 * @param member
	 * @return the score
	 */
	public Double zscore(final String key, final String member);

	/**
	 * Creates a union or intersection of N sorted sets given by keys k1 through
	 * kN, and stores it at dstkey. It is mandatory to provide the number of
	 * input keys N, before passing the input keys and the other (optional)
	 * arguments.
	 * <p>
	 * As the terms imply, the {@link #zinterstore(String, String...)
	 * ZINTERSTORE} command requires an element to be present in each of the
	 * given inputs to be inserted in the result. The
	 * {@link #zunionstore(String, String...) ZUNIONSTORE} command inserts all
	 * elements across all inputs.
	 * <p>
	 * Using the WEIGHTS option, it is possible to add weight to each input
	 * sorted set. This means that the score of each element in the sorted set
	 * is first multiplied by this weight before being passed to the
	 * aggregation. When this option is not given, all weights default to 1.
	 * <p>
	 * With the AGGREGATE option, it's possible to specify how the results of
	 * the union or intersection are aggregated. This option defaults to SUM,
	 * where the score of an element is summed across the inputs where it
	 * exists. When this option is set to be either MIN or MAX, the resulting
	 * set will contain the minimum or maximum score of an element across the
	 * inputs where it exists.
	 * <p>
	 * <b>Time complexity:</b> O(N) + O(M log(M)) with N being the sum of the
	 * sizes of the input sorted sets, and M being the number of elements in the
	 * resulting sorted set
	 * 
	 * @param dstkey
	 * @param sets
	 * @return Integer reply, specifically the number of elements in the sorted
	 *         set at dstkey
	 */
	public Long zunionstore(final String dstkey, final String... sets);
}